package com.linfeng.server.gateway.handler;

import cn.hutool.json.JSONUtil;
import com.linfeng.component.common.exception.CustomException;
import com.linfeng.component.common.response.ResponseEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebExceptionHandler;
import reactor.core.publisher.Mono;

@Slf4j
@Configuration
@Order(-1)
public class ExceptionHandler implements WebExceptionHandler {

//    public ExceptionHandler(ErrorAttributes errorAttributes, WebProperties.Resources resources, ErrorProperties errorProperties, ApplicationContext applicationContext) {
//        super(errorAttributes, resources, errorProperties, applicationContext);
//    }

//    @Override
//    protected Mono<ServerResponse> renderErrorResponse(ServerRequest request) {
//        // 最终是用responseBodyMap来生成响应body的
//        Map<String, Object> responseBodyMap = new HashMap<>();
//
//        // 这里和父类的做法一样，取得DefaultErrorAttributes整理出来的所有异常信息
//        Map<String, Object> error = getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.ALL));
//
//        // 原始的异常信息可以用getError方法取得
//        Throwable throwable = getError(request);
//
//        responseBodyMap.put("returnCode", "my error code");
//        responseBodyMap.put("errorMsg", throwable.getMessage());
//        responseBodyMap.put("body", null);
//        return ServerResponse
//                // http返回码
//                .status(HttpStatus.INTERNAL_SERVER_ERROR)
//                // 类型和以前一样
//                .contentType(MediaType.APPLICATION_JSON)
//                // 响应body的内容
//                .body(BodyInserters.fromValue(responseBodyMap));
//    }

    @Override
    public Mono<Void> handle(ServerWebExchange exchange, Throwable throwable) {

        log.info("ExceptionHandler------handle");
        ServerHttpResponse response= exchange.getResponse();
        if (response.isCommitted()) {
            return Mono.error(throwable);
        } else {
            response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
            Integer responseCode = response.getStatusCode().value();

            if (throwable instanceof ResponseStatusException) {
                responseCode = ((ResponseStatusException) throwable).getStatus().value();
            } else if (throwable instanceof CustomException) {
                responseCode = ((CustomException) throwable).getCode();
            }
            ResponseEntity responseEntity = new ResponseEntity(responseCode, throwable.getMessage());

            return response.writeWith(Mono.just(response.bufferFactory().wrap(JSONUtil.toJsonStr(responseEntity).getBytes())));
        }
    }
}
